package cn.itsource.hrm.service.impl;

import cn.itsource.hrm.ai.IAIContentAuditService;
import cn.itsource.hrm.client.CourseDocClient;
import cn.itsource.hrm.config.RabbitMQConfig;
import cn.itsource.hrm.doc.CourseDoc;
import cn.itsource.hrm.domain.*;
import cn.itsource.hrm.dto.CourseDto;
import cn.itsource.hrm.enums.CourseGrade;
import cn.itsource.hrm.exception.ErrorCode;
import cn.itsource.hrm.exception.ValidUtil;
import cn.itsource.hrm.mapper.*;
import cn.itsource.hrm.query.CourseQuery;
import cn.itsource.hrm.service.ICourseService;
import cn.itsource.hrm.util.AjaxResult;
import cn.itsource.hrm.util.PageList;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yaosang
 * @since 2022-01-08
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

//    Data level:save remove update loadById loadAll
//    business level:add del edit/update getById getAll query sellect find
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;

    @Autowired
    private IAIContentAuditService aiContentAuditService;

    @Autowired
    private CourseAuditLogMapper courseAuditLogMapper;

    @Autowired
    private CourseOnlineLogMapper courseOnlineLogMapper;
    @Override
    public PageList<Course> selectPageList(CourseQuery query) {
        Page page = new Page(query.getPage(),query.getRows());
        List<Course> datas = courseMapper.loadPageList(page,query);
        return new PageList<>(page.getTotal(),datas);
    }

    @Override
    @Transactional
    public void updateById(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        //1 相关校验
        //1.1 适用jsr303完成null校验
        //1.2 对课程等级进行合法性校验

        CourseGrade grade = CourseGrade.getGrade(course.getGradeId());
        ValidUtil.assertNotNull(grade, ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);

        String content = course.getName()+" "+ course.getForUser()+" "+ courseDetail.getIntro()+" "+ courseDetail.getDescription();
        AjaxResult ajaxResult = aiContentAuditService.audit(content, null, null);
        int status = ajaxResult.isSuccess()?1:-1;
        //2 正在操作
        //添加课程
        course.setStatus(status);
        courseMapper.updateById(course);

        //添加市场信息
        courseMarketMapper.updateById(courseMarket);

        //添加课程详情
        courseDetailMapper.updateById(courseDetail);
        //3 进行百度内容自动审核
        auditHandle(ajaxResult.getMessage(),course);
    }

    @Override
    @Transactional
    public void insert(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        //1 相关校验
        //1.1 适用jsr303完成null校验
        //1.2 对课程等级进行合法性校验

        CourseGrade grade = CourseGrade.getGrade(course.getGradeId());
        ValidUtil.assertNotNull(grade, ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);

        String content = course.getName()+" "+ course.getForUser()+" "+ courseDetail.getIntro()+" "+ courseDetail.getDescription();
        AjaxResult ajaxResult = aiContentAuditService.audit(content, null, null);
        int status = ajaxResult.isSuccess()?1:-1;
        //2 正在操作
        //添加课程
        course.setStatus(status);
        courseMapper.insert(course);

        //添加市场信息
        Long courseId = course.getId();
        courseMarket.setId(courseId);
        courseMarketMapper.insert(courseMarket);

        //添加课程详情
        courseDetail.setId(courseId);
        courseDetailMapper.insert(courseDetail);

        //3 进行百度内容自动审核
        auditHandle(ajaxResult.getMessage(),course);
    }

    @Autowired
    private CourseDocClient courseDocClient;

    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Override
    @Transactional
    public AjaxResult online(List<Long> ids) {
        //1 判null
        ValidUtil.assertListNotNull(ids,ErrorCode.CODE_400_COURSE_LIST_ILLEGAL);
        //2 修改数据库状态
        courseMapper.online(ids);
        //3 远程调用feign接口，实现添加ES数据
        List<CourseDoc> courseDocs = new ArrayList<>();
        List<CourseOnlineLog> courseOnlineLogs = new ArrayList<>();
        for (Long id : ids) {
            CourseDoc courseDoc = new CourseDoc();
            //处理course里面值
            Course course = courseMapper.selectById(id);
            BeanUtils.copyProperties(course,courseDoc);

            //处理课程类型
            Long courseTypeId = course.getCourseTypeId();
            CourseType courseType = courseTypeMapper.selectById(courseTypeId);
            courseDoc.setCourseTypeName(courseType.getName());
            //处理影响信息
            CourseMarket courseMarket = courseMarketMapper.selectById(id);
            BeanUtils.copyProperties(courseMarket,courseDoc);
            courseDocs.add(courseDoc);

            //处理上下线日志
            CourseOnlineLog log = course2OnlineLog(course);
            courseOnlineLogs.add(log);
        }
        courseDocClient.batchAdd(courseDocs);
        //4 上线历史记录。
        courseOnlineLogMapper.batchSave(courseOnlineLogs);

        //5 消息推送
        publishMessage(ids);

        //6 远程调用页面静态化服务，完成课程详情页静态 一个课程就有一个静态页面(id.html)，以空间换时间的效果。
        //怎么访问，安装约定大于配置，通过id.html
        return AjaxResult.me();
    }

    @Autowired
    private RabbitTemplate rabbitTemplate;
    //消息推送
    private void publishMessage(List<Long> ids) {
        //sms
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.sms",ids);
        //email
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.email",ids);
        //system
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.system",ids);
    }

    private CourseOnlineLog course2OnlineLog(Course course) {
        CourseOnlineLog log = new CourseOnlineLog();
        log.setCourseId(course.getId());
        log.setCourseName(course.getName());
        log.setState(1);
        log.setOnlineTime(new Date());
        return log;
    }

    @Override
    @Transactional
    public AjaxResult offline(List<Long> ids) {
        //1 判null
        ValidUtil.assertListNotNull(ids,ErrorCode.CODE_400_COURSE_LIST_ILLEGAL);
        //2 修改数据库状态
        courseMapper.offline(ids);
        //3 远程调用feign接口，实现删除ES数据
        courseDocClient.batchDel(ids);
        //4 下线历史记录。
        batchOffLineLog(ids);
        return AjaxResult.me();
    }

    private void batchOffLineLog(List<Long> ids) {
        List<CourseOnlineLog> courseOnlineLogs = ids.stream().map(id -> {
            Course course = courseMapper.selectById(id);
            CourseOnlineLog log = new CourseOnlineLog();
            log.setCourseId(course.getId());
            log.setCourseName(course.getName());
            //下线
            log.setState(0);
            log.setOfflineTime(new Date());
            return log;
        }).collect(Collectors.toList());
        courseOnlineLogMapper.batchSave(courseOnlineLogs);
    }

    private void auditHandle(String message,Course course) {
        CourseAuditLog auditLog = course2CourseAuditLog(course,message);
        courseAuditLogMapper.insert(auditLog);
    }

    private CourseAuditLog course2CourseAuditLog(Course course, String message) {
        CourseAuditLog auditLog = new CourseAuditLog();
        auditLog.setCourseId(course.getId());
        auditLog.setCourseName(course.getName());
        auditLog.setState(course.getStatus());
        String note = course.getStatus()!=-1 ?"审核通过": message;
        auditLog.setNote(note);
        auditLog.setAuditTime(new Date());
        auditLog.setAuditAdminId(null);
        auditLog.setAuditAdminName("系统自动审核");
        return auditLog;
    }

    @Override
    @Transactional
    public boolean deleteById(Serializable courseId) {

        //删除详情
        courseDetailMapper.deleteById(courseId);

        //删除营销信息
        courseMarketMapper.deleteById(courseId);

        //删除课程信息
        courseMapper.deleteById(courseId);

        //是否删除审核日志，上下架日志，看你的业务逻辑
        return  true;
    }
}
